package com.zlx.store.coupon.job;

import com.zlx.store.coupon.constants.CouponConstant;
import com.zlx.store.coupon.dao.CouponDao;
import com.zlx.store.coupon.dao.CouponRelateUserDao;
import com.zlx.store.coupon.service.CouponService;
import com.zlx.store.coupon.service.impl.CouponServiceImpl;
import com.zlx.store.domain.entity.Coupon;
import com.zlx.store.domain.entity.CouponRelateUser;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 用于定时更新中间表到数据库中,过期的不更新
 * 更新之后将自动预热队列中的优惠券预热到队列中
 */
@Component
public class CouponJob extends QuartzJobBean {
    @Autowired
    CouponService couponService;
    @Autowired
    CouponDao couponDao;
    @Autowired
    CouponRelateUserDao couponRelateUserDao;
    @Autowired
    RedisTemplate couponRedisTemplate;
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 定时同步redis和mysql以及自动预热优惠券
     * @param context
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        //1.删除整张库存表
        couponRedisTemplate.delete(CouponConstant.PREPARING_COUPON_STOCK);

        //2.同步redis和数据库,删除整张临时表
        Map<Long, Set<Long>> map = couponRedisTemplate.opsForHash().entries(CouponConstant.TEMP_COUPON_COUNT);
        for (Map.Entry<Long, Set<Long>> entry : map.entrySet()) {
            CouponRelateUser couponRelateUser = new CouponRelateUser();
            couponRelateUser.setUserId(entry.getKey());
            for (Long couponId : entry.getValue()) {
                couponRelateUser.setCouponId(couponId);
                couponRelateUserDao.insert(couponRelateUser);
            }
        }
        //删除整个临时表
        couponRedisTemplate.delete(CouponConstant.TEMP_COUPON_COUNT);

        //3.根据数量表删除redis中的防重队列,再删除数量表
        Map<Long, Long> couponMap = couponRedisTemplate.opsForHash().entries(CouponConstant.PREPARING_COUPON_COUNT);
        Set<Long> keySet = couponMap.keySet();
        for (Long tempCouponId : keySet) {
            couponRedisTemplate.delete(CouponConstant.AVOID_DUPLICATION_QUEUE + tempCouponId);
        }
        couponRedisTemplate.delete(CouponConstant.PREPARING_COUPON_COUNT);

        //4.读出自动预热队列中的优惠券对象,清空自动预热队列
        Map<Long, Coupon> entries = couponRedisTemplate.opsForHash().entries(CouponConstant.AUTO_PREPARE_QUEUE);

        //遍历全部优惠券对象
        for (Coupon c : entries.values()) {
            if (c.getCouponEndTime().before(new Date())) {
                //过期的不预热,并自动删除
                couponRedisTemplate.opsForHash().delete(CouponConstant.AUTO_PREPARE_QUEUE, c.getCouponId());
                continue;
            }
            if (couponDao.selectById(c.getCouponId()) == null) {
                //不存在在数据库中也不预热
                continue;
            }
            // 如果条件都满足,则将当前优惠券对象加入redis中
            couponRedisTemplate.opsForHash().put(CouponConstant.PREPARING_COUPON_STOCK, c.getCouponId(), c);
            //由于临时表只需要查询优惠券数量,所以只存入数量即可
            couponRedisTemplate.opsForHash().put(CouponConstant.PREPARING_COUPON_COUNT, c.getCouponId(), c.getCouponStock());
        }
        couponRedisTemplate.delete(CouponConstant.AUTO_PREPARE_QUEUE);
    }


}
